package com.chaosj.memory.handlers;

import com.chaosj.memory.IToolHandler;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @className: AbstractToolHandler
 * @description:
 * @author: caoyangjie
 * @date: 2021/8/10
 **/
@Slf4j
public abstract class AbstractToolHandler<T> implements IToolHandler<T> {
    protected static Random next = new Random();

    @Override
    public void round(StringBuffer stringBuffer, boolean isBefore) {
        if( isBefore ){
            stringBuffer.append(String.format("***********************%s start **********************\n",name()));
        }else{
            stringBuffer.append(String.format("***********************%s end ************************\n",name()));
        }
    }

    @Override
    public String description() {
        return getResourceContent(String.format("cmd/%s.command",name()), -1," ").stream().collect(Collectors.joining("\n"));
    }

    @Override
    public boolean support(String cmd) {
        return name().equalsIgnoreCase(cmd);
    }

    protected List<String> getResourceContent(String classPath, int lineCount, String splitter){
        Path path = null;
        final List<String> lines = new ArrayList<>();
        try {
            path = Paths.get(ClassLoader.getSystemClassLoader().getResource(classPath).toURI());
            if( path.toFile().isDirectory() ){
                lines.addAll(Arrays.stream(path.toFile().listFiles()).map(f-> {
                    try {
                        return Files.readAllLines(f.toPath());
                    } catch (IOException e) {
                    }
                    return new ArrayList<String>();
                }).reduce(new ArrayList<String>(),(l1,l2)->{
                    if( l2!=null ){
                        l1.addAll(l2);
                    }
                    return l1;
                }));
            }else{
                lines.addAll(Files.readAllLines(path, Charset.forName("UTF-8")));
            }
            if( lineCount==-1 ){
                return lines;
            }else{
                Supplier<Integer> supplier = null;
                if( lineCount < 0 ){
                    lineCount = 0 - lineCount;
                    supplier = ()-> next.nextInt(lines.size());
                }else{
                    AtomicInteger incr = new AtomicInteger(0);
                    supplier = ()-> incr.getAndIncrement();
                }
                return Stream.generate(supplier).limit(lineCount).map(index-> (index+1)+" <-> "+Splitter.on(splitter).splitToList(lines.get(index)).stream().findFirst().get()).collect(Collectors.toList());
            }
        } catch (URISyntaxException | IOException e) {
            String info = "无法获取到资源文件"+classPath;
            log.error(info);
            lines.add(info);
        }
        return lines;
    }

    protected void formatter( List<String> lines, StringBuffer buffer) {
        lines.forEach( line-> buffer.append("| ").append(line).append(" |\n") );
    }
}
